<!--
远程循环组件
:mc-config="{'url':'/public/item.json','method':'get','params':[],'fields':[],mcIntervalSeconds:200,watch:""}"
    //watch 观察变量 如果这个变量更新 我就刷新 逗号分割多个


mcIntervalSeconds:每隔多少秒触发一次刷新数据

//参考https://chenxuan1993.gitee.io/component-document/index_prod#/component/seamless-default
https://gitee.com/FElinjie/vue-seamless-scroll?_from=gitee_search

key	description	default	val
step	the faster the rolling speed is faster	1	Number
limitMoveNum	start seamless scrolling minimum data length	5	Number
hoverStop	mouse hover control is enabled	true	Boolean
direction	0 down、 1 up 、 2 left 、 3 right	1	Number
openTouch	open mobile touch	true	Boolean
singleHeight	one single stop height(default zero is seamless) => direction 0/1	0	Number
singleWidth	one single stop width(default zero is seamless) => direction 2/3	0	Number
waitTime	one single data stop wait time(ms)	1000	Number
switchOffset	the left and right buttons distance from the left and right sides (px)	30	Number
autoPlay	Less than 1.1.17 version needs to be set to false when manually switching	true	Boolean
switchSingleStep	the size of a single step switch (px)	134	Number
switchDelay	the animation time of a single step switch(ms)	400	Number
switchDisabledClass	the className of the switch parent element that cannot be clicked	disabled	String
isSingleRemUnit	singleHeight and singleWidth Whether to enable the rem metric	false	Boolean

:mc-scroll="{open:true|false,direction:0|1|2滚动方向,step:1滚动速度,hoverStop:false悬停停止,singleHeight:26单行停顿,waitTime:2500单行停顿时间}"
基本用法。switch控制切换 direction:2 autoPlay: false,switchSingleStep: 140
switch控制切换 自定义switchSingleStep(步数大小)和switchDelay(切换时间)direction:2autoPlay: false,switchSingleStep: 100,switchDelay:50
基本用法。向右滚动 direction:2 limitMoveNum: 4
基本用法。向左滚动 direction:2 limitMoveNum: 2
先让表格发展一段时间
-->
<template>
  <el-row class="mc-el-row mc-on-shade" v-bind="$attrs" v-on="$listeners":style="{overflow:overflow}">
    <!-- 帮助信息 -->
    <el-col v-if="assist.show"  class="mc-el-row-assist" :span="24">
      <el-tag class="mc-el-row-assist-tag" @click="assistClick(1)">scope.row</el-tag>
      <el-switch @change="switchViewAllData" v-model="assist.viewAllData" @click="assistClick(2)"></el-switch>
    </el-col>
      <slot name="header"></slot>
      <slot name="query" :row="queryData" :vue="vueIns"></slot>
    <el-col class="mc-el-row-content" :span="24" v-if="mcScroll.open">
      <vue-seamless-scroll :data="dataList" :class-option="mcScroll" :style="{overflow:'hidden'}">
        <template v-for="(item,i) in dataList">
          <slot name="row" :row="item" :rowIndex="i" :index="i" :vue="vueIns"></slot>
        </template>
      </vue-seamless-scroll>
    </el-col>
    <template v-for="(item,i) in dataList" v-else>
      <slot name="row" :row="item" :rowIndex="i" :index="i" :vue="vueIns"></slot>
    </template>

    <el-col class="mc-el-row-pager" :span="24" v-if="mcPage.open">
      <el-pagination  layout="prev,pager,next"
                     :total="mcPageObj.pageTotal" :current-page.sync="mcPageObj.currentPage"
                     @current-change="pageChange"
                     :page-size="mcPageObj.pageLimit"
                     :pager-count="mcPage.pagerCount"
                     :small="mcPage.small"
                     :prev-text="mcPage.prevText"
                     :next-text="mcPage.nextText"
                      :background="mcPage.background"
      >
      </el-pagination>
    </el-col>
    <slot name="footer" :data="dataList" :vue="vueIns"></slot>
  </el-row>
</template>

<script>
import VueSeamlessScroll from 'vue-seamless-scroll'
import McElCol from "./McElCol.vue";
import McCommon from "./McCommon";

export default {
  name: 'mc-el-row',
  data () {
    return {
      rendered:false,
        mcPageObj:{
          pageTotal:100,
          currentPage:1,
          pageLimit:10,
        },
        //兼容老数据
        backendList:[],
        dataListCache:[],
        assist: {show:window.iframeUi,viewAllData:false},
        apiInfo:"",
        overflow:this.mcScroll.open?"hidden":"auto",
        vueIns : this,
      /*查询区域数据*/
        queryData:{}
    }
  },
  components:{
    VueSeamlessScroll
  },
  props:{
    //找个莫名其妙的-10000来标记用户是否配置了data.sync属性 兼容老的组件 即使不配置data属性 也能跑起来 也别加类型
    'data':{},
    //静态删除的数组
    'apiDeleteData':{},
    //版本号 v1还不支持data v2开始支持外面传data
    'mcVersion':{type:String,default:"v1"},
    'mcConfig':{type:Object,default:null},
    'mcPage':{type:Object,default:function (){return {open:false,pagerCount:7}}},
    //{open:true}
    'mcScroll':{type:Object,default: function(){return {open:false}}},
    //参数值 这样可以接受变量 表达式之类的，暂时20个足够使用了
    'mcv1':{type:[String,Number,Date,Boolean,Array,Object],default:null},
    'mcv2':{type:[String,Number,Date,Boolean,Array,Object],default:null},
    'mcv3':{type:[String,Number,Date,Boolean,Array,Object],default:null},
    'mcv4':{type:[String,Number,Date,Boolean,Array,Object],default:null},
    'mcv5':{type:[String,Number,Date,Boolean,Array,Object],default:null},
    'mcv6':{type:[String,Number,Date,Boolean,Array,Object],default:null},
    'mcv7':{type:[String,Number,Date,Boolean,Array,Object],default:null},
    'mcv8':{type:[String,Number,Date,Boolean,Array,Object],default:null},
    'mcv9':{type:[String,Number,Date,Boolean,Array,Object],default:null},
    'mcv10':{type:[String,Number,Date,Boolean,Array,Object],default:null},
    'mcv11':{type:[String,Number,Date,Boolean,Array,Object],default:null},
    'mcv12':{type:[String,Number,Date,Boolean,Array,Object],default:null},
    'mcv13':{type:[String,Number,Date,Boolean,Array,Object],default:null},
    'mcv14':{type:[String,Number,Date,Boolean,Array,Object],default:null},
    'mcv15':{type:[String,Number,Date,Boolean,Array,Object],default:null},
    'mcv16':{type:[String,Number,Date,Boolean,Array,Object],default:null},
    'mcv17':{type:[String,Number,Date,Boolean,Array,Object],default:null},
    'mcv18':{type:[String,Number,Date,Boolean,Array,Object],default:null},
    'mcv19':{type:[String,Number,Date,Boolean,Array,Object],default:null},
    'mcv20':{type:[String,Number,Date,Boolean,Array,Object],default:null},

  },
  computed:{
    dataList:{
      get(){
        if(this.data||this.mcVersion=='v2'){//新版
          return this.data;
        }
        //兜底最老版本
        return this.backendList;
      },
      set(newData){
        if(this.data || this.mcVersion=='v2'){//新版
          this.$emit("update:data",newData);
          return;
        }
        this.backendList = newData;
      }
    }
  },
  watch:{
        dataList:{
          handler(newData){
            this.$emit("mc-on-data-change",{data:newData})
          },
          deep:true
        }
  },
  updated:function(){
    if(window.iframeUi){
      this.$nextTick(function(){//虚拟dom转化为真实dom后触发 这样动态新增的结构里 仍然可以被拖拽
        window.iframeUi.magicalApi.addApiTask({methodName:"refreshDragEvent"});
      })
    }
  },
  created () {
    //console.log("mc-el-row created");
    //考虑下监听
    var _t = this;
    this.$nextTick(function(){//虚拟dom转化为真实dom后触发
      var pageVue = window.MC ? window.MC['vue'] : window.vueMc;
      if(typeof pageVue !='undefined' && pageVue && this.mcConfig){
        var watch = this.mcConfig.watch;
        if(watch){
          var watchVars = watch.trim().split(",");
          for(var n=0;n<watchVars.length;n++){
            var varName = watchVars[n];
            pageVue.$watch(varName,function(n,o){
              _t.reload();
            },{deep:true});
          }
        }
      }
    });
    if(!window.iframeUi){//布局器内 接口都缓存了 自动刷新没意义 所以不在布局器内 才让定时刷新有效 !window.iframeUi是对的
      var _t = this;
      if(!this.mcConfig){
        return;
      }
      var intervalTimer = null;
      var mcIntervalSeconds = this.mcConfig.mcIntervalSeconds||0;
      if(mcIntervalSeconds>0){
        intervalTimer = window.setInterval(function (){
          _t.reload();
        }, mcIntervalSeconds*1000);
      }
      //布局器会主动清理此定时任务 避免重复注册
      if(intervalTimer&&window.iframeUi){
        window._mcCacheIntervals.push(intervalTimer)
      }
    }

  },
  mounted(){
    //自动刷新越晚越好 因为会用到动态变量 如果还没准备好 就获取不到了
    this.$nextTick(() => {
      this.reload();
      //最后一个参数 可以让事件冒泡 也就是所有的组件滚动条都能监听
      window.addEventListener("scroll",this.scrollEvent,true)
    })
  },
  destroyed(){
    window.removeEventListener('scroll',this.scrollEvent,true);
  },

  methods:{
    scrollEvent:function (e){
      if(!this.rendered){
        this.rendered = this.reload();
      }else {
        //这里必须放 不然还取消不了事件呢
        window.removeEventListener('scroll',this.scrollEvent,true)
      }
    },
    reload:function(){
      this.$nextTick(()=>{
        this.refresh();
      })
    },
    pageChange:function(page){
      this.reload();
    },
    refresh(){
      if(!McCommon.util.isInWindowView(this.$el)){
        return false;
      }
      this.rendered = true;
      //一定要解绑 当组件被渲染过一次时 滚动监听就不再需要了 懒加载过了 还滚动啥
      window.removeEventListener('scroll',this.scrollEvent,true)
      // console.log("refresh")

      var request = this.$magicaltool.request;
      var _t = this;
      if(this.mcConfig && this.mcConfig.url){
          var url = this.mcConfig.url;
          var method = this.mcConfig.method||'post';
          var limit = this.mcConfig.limit||20;
          this.mcPageObj.pageLimit = limit;

          var page = this.mcPageObj.currentPage||1;

          var param = {};
          var ncv = request.util.collectMcNameCompareValue(this);
          if(request.util.isMcQueryUrl(url) || request.util.isContentTypeJson(this.mcConfig.contentType)){
              param = request.util.paramsTomMcQuery(ncv || this.mcConfig.params);
              if(this.mcConfig.fields && this.mcConfig.fields.length>0){
                  param.fields = this.mcConfig.fields
              }
              //添加查询slot的参数
              if(this.queryData){
                for(var key in this.queryData){
                  var value = this.queryData[key];
                  if(value !== null && value !== "" && typeof value != 'undefined'){
                    param.param[key] = value;
                  }
                }
              }
              url += url.indexOf("?")!=-1 ? "&" : "?";
              url += "limit="+limit;
              url += "&page="+page;
              param.order = request.util.mcQueryOrder(this.mcConfig.orders);
          }else{
              param = request.util.paramsToJson(ncv||this.mcConfig.params);
              param.limit = limit;//加个关键词入参
              param.page = page;//加个关键词入参
              //添加查询slot的参数
              if(this.queryData){
                for(var key in this.queryData){
                  var value = this.queryData[key];
                  if(value !== null && value !== "" && typeof value != 'undefined'){
                    param[key] = value;
                  }
                }
              }
          }
          request.axios({keepUrl:false,contentType:this.mcConfig.contentType,cache:true,$vue:this,url:url,method:method,param:param}).then(function(res){
            _t._setTableData(res);
          })
      }else {
        if(window.iframeUi){
          this.dataList = McCommon.util.addMcExtraToList([{}]);
        }
      }
      return true;
    },
    _setTableData:function(res){
      var _t = this;
      //数组字段 转下
      _t.$emit("before-render-data",{res:res});
      McCommon.util.afterQuery(res);
      if(typeof res['count']!='undefined'){
        this.mcPageObj.pageTotal = res.count;
      }
      var resData = res.data;
      if(!Array.isArray(resData)){
        resData = [resData];//如果返回的数据不是数组，那么我们转成一维数组 这样就可以兼容更多场景的api接口
      }
      McCommon.util.addMcExtraToList(resData);
      this.dataListCache = resData;
      if(resData.length>0){
        if(this.showAllDataList()){
          this.dataList = resData;
        }else {//设计阶段仅展示一条数据
          this.dataList = [resData[0]];
        }
      }else {
        if(window.iframeUi){//没数据 给一个默认数据
          this.$message({type:"info",message:"检测到您的接口未返回数据，特为您添加一条假数据"})
          this.dataList = McCommon.util.addMcExtraToList([{}]);
        }else {
          this.dataList = [];
        }
      }
      _t.$emit("after-render-data",{res:res,vue:this});
    },
    //预览模式
    showAllDataList(){
      return !window.iframeUi;
    },
    assistClick(type){
      switch(type){
          case  1:
            var obj = {};
            if(this.dataListCache&&this.dataListCache.length>0){
              obj = this.dataListCache[0];
            }
            var jsonHtml = JSON.stringify(obj,null,2);
            var html = "row:\n"+jsonHtml+"\nvue:可以调用API的组件实例\nrowIndex:当前行索引"+
            McCommon.util.parent.layer({title:"scope的数据结构",content:jsonHtml})
          break;
      }
    },
    switchViewAllData(){
      if(this.assist.viewAllData){
        this.dataList = this.dataListCache;
      }else {
        if(this.dataListCache && this.dataListCache.length>0){
          this.dataList = [this.dataListCache[0]];
        }
      }
    },
    getData(){
      return this.dataList;
    },
    getQuery:function (){
      return this.queryData;
    },
    getApiDeleteData:function(){
      return this.apiDeleteData;
    },
    //api开头表示不操作库
    apiAddRow:function({data,index}){
      McCommon.util.addRow(this.dataList,data,index)
    },
    /**
     * index:删除的行索引
     * pk:主键名称 比如id 因为删除主键记录到删除数组里才有意义，方便数据库操作
     */
    apiDeleteRow:function({index,pk}){
      var deleteRow = McCommon.util.deleteRow(this.dataList,index)
      if(pk){//指定了主键并且存在
        if(deleteRow[pk]){
          if(this.apiDeleteData){
            this.apiDeleteData.push(deleteRow);
          }else{
            this.$emit("update:api-delete-data",[])
            this.$nextTick(()=>{
              if(this.apiDeleteData){
                this.apiDeleteData.push(deleteRow);
              }
            })
          }
        }
      }
    },
    apiSetDeleteData:function({data}){
      this.$emit("update:api-delete-data",data);
    },
    apiDuplicateRow:function({data,index,ignores}){
      var entity = JSON.parse(JSON.stringify(data));
      if(ignores){
        for(var i=0;i<ignores.length;i++){
          if(ignores[i]){
            delete entity[ignores[i]];
          }
        }
      }
      McCommon.util.addRow(this.dataList,entity,index)
    },
    /**
     * 设置表格数据 delete：处理deleteList的策略all:=全部数据 empty:=[] keep:保持不变
     * @param {data:[],count:0,code:0,delete:'all|empty|keep'} res
     */
    apiSetData:function(res){
      if(res.data==null){
        res.data=[];
      }
      if(res.delete=='all'){
        var table = this.dataList;
        this.apiSetDeleteData({data:JSON.parse(JSON.stringify(table))})
      }else if(res.delete == 'empty'){
        this.apiSetDeleteData({data:[]})
      }
      this._setTableData(res);
    }
  }
}
</script>

<style lang="scss">
    .mc-el-row{
      overflow: auto;
    }
    .mc-el-row-assist{
      display:none;
      position:absolute;
      left:0px;
      top:0px;
      width: 130px;
      z-index:1001;
    }
    .mc-el-row-assist-tag{
      color:#409EFF;
      height:unset;
      line-height:unset;
    }
    .magicalcoder-dragging .mc-el-row-assist{
      display:block;
    }
    .mc-el-row-assist-dialog{
      z-index: 99999 !important;
    }
    .magicalcoder-dragging .mc-el-row-query,
    .magicalcoder-dragging .mc-el-row-content,
    .magicalcoder-dragging .mc-el-row-body
    {
      position: relative;
    }
    .magicalcoder-dragging .mc-el-row-query:before{
      content: '查询';
      color:#4551ff;
      font-weight:bold;
      font-size: xx-small;
      position: absolute;
      right: 0px;
      top: 0px;
    }
    .magicalcoder-dragging .mc-el-row-content:before{
      content: '循环体';
      color:#4551ff;
      font-weight:bold;
      font-size: xx-small;
      position: absolute;
      right: 0px;
      top: 0px;
    }
    .magicalcoder-dragging .mc-el-row-body:before{
      content: '循环体';
      color:#4551ff;
      font-weight:bold;
      font-size: xx-small;
      position: absolute;
      right: 0px;
      top: 0px;
    }
    /*配置设计器界面边框颜色*/
    .magicalcoder-dragging .mc-el-row.drag-mc-pane{
      border-color: #5976cf;
    }
</style>
